/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
 *
 * Zhiqim UI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
 
+(function(Z) 
{//BEGIN 
// @version v1.1.0 @author zouzhigang 2015-11-12 新建与整理

// 定义浮动层
// 1.触发者，支持条件为hover表示移入移出，click表示点击，点击其他地方则关闭
// 2.方位，支持方位上下左右，对齐上下左右居中，偏移向左向上，和指定宽度和高度
// 3.内容，支持是否有箭头和HTML文本
// 4.颜色，支持边框和背景颜色
// 用于如提示信息(ToolTip)和下拉列表等(DropdownList)使用

Z.Floater = Z.Class.newInstance();
Z.Floater.v = "8.0.4";
Z.Floater.prototype = 
{
    defaults :
    {
        elem:null,
        event: "hover",
        
        //方位
        placement: "bottom",
        align: "center",
        top: 0,
        left: 0,
        width: 130,
        height: 25,
        
        //内容
        hasArrow: true,
        id: null,
        text: null,
        
        //颜色
        color: "#333",
        borderColor: "#c3c3c3",
        backgroundColor: "#fff"
    },
    
    execute: function()
    {
        this.$elem = Z.$elem(this.elem, "Z.Floater");
        this.id = this.id || "z-floater-"+Z.random(4);
        
        var floater = '<div class="z-floater" id="'+this.id+'">' +
                      '    <div class="z-arrow z-px8"><span></span></div>' +
                      '    <div class="z-content"></div>' +
                      '</div>';
        this.$floater = Z(floater).appendToPos(this.$elem.parent());
        this.$arrow = this.$floater.find(".z-arrow");
        if (!this.hasArrow)
        {//删除箭头
            this.$arrow.remove();
        }
        
        this.$content = this.$floater.find(".z-content");
        this.$content.css({"width": this.width, "minHeight": this.height});
        this.$content.css({"color": this.color, "borderColor": this.borderColor,"backgroundColor": this.backgroundColor});
        this.$content.html(this.text);
        
        if (this.height < 25){
        	this.$content.css("line-height", this.height);
        }
        
        this.elemLeft = this.$elem.offsetLeft();
        this.elemTop = this.$elem.offsetTop();
        this.elemWidth = this.$elem.offsetWidth();
        this.elemHeight = this.$elem.offsetHeight();
        this.elemHalfWidth = this.elemWidth / 2;
        this.elemHalfHeight = this.elemHeight / 2;
        this.contentWidth = this.$content.offsetWidth();
        this.contentHeight = this.$content.offsetHeight();
        this.contentHalfWidth = this.contentWidth / 2;
        this.contentHalfHeight = this.contentHeight / 2;
        
        //默认可见，计算完宽高之后隐藏
        this.$floater.hide();
        
        if (this.event == "hover")
        {//为移入移出事件，鼠标在元素和提示上显示
            this.$elem.mouseover(this.show, this);
            this.$elem.mouseout(this.hide, this);
            this.$floater.mouseover(this.show, this);
            this.$floater.mouseout(this.hide, this);
        }
        else if (this.event == "click")
        {//为点击事件，点击触发者和浮动层时停止冒泡，其他地方隐藏
            Z(document).click(this.hide, this);
            this.$elem.click(function(e){this.show();Z.E.stop(e);}, this);
            this.$floater.click(function(e){Z.E.stop(e);}, this);
        }
        else
        {//为要求主动关闭
            this.show();
        }
    },
    arrowBorderColor: function()
    {
        switch(this.placement)
        {
            case "top": return this.borderColor + " transparent transparent";
            case "left": return "transparent transparent transparent "+this.borderColor;
            case "right": return "transparent "+this.borderColor+" transparent transparent";
            default: return "transparent transparent "+this.borderColor;
        }
    },
    arrowBackgroundColor: function()
    {
        switch(this.placement)
        {
            case "top": return this.backgroundColor + " transparent transparent";
            case "left": return "transparent transparent transparent "+this.backgroundColor;
            case "right": return "transparent "+this.backgroundColor+" transparent transparent";
            default: return "transparent transparent "+this.backgroundColor;
        }
    },
    placeTop: function()
    {//放置上面
        var top = this.elemTop - this.contentHeight - (this.hasArrow?8:0) - this.top;
        var arrowTop = this.contentHeight - 1;
        var left, arrowLeft;
        
        switch (this.align) 
        {
            case "left": left = this.elemLeft;arrowLeft = 10;break;
            case "right": left = this.elemLeft - this.contentWidth + this.elemWidth;arrowLeft = this.contentWidth - 16 - 10;break;
            default: left = this.elemLeft + this.elemHalfWidth - this.contentHalfWidth;arrowLeft = this.contentHalfWidth - 8 - 1;break;
        }
        
        this.$floater.show().css({left: left, top: top});
        if (this.hasArrow)
        {
            this.$arrow.css({left: arrowLeft, top: arrowTop});
        }
    },
    placeLeft: function()
    {//放置左边
        var left = this.elemLeft - this.contentWidth - (this.hasArrow?8:0) - this.left;
        var arrowLeft = this.contentWidth - 4 + 1;
        var top, arrowTop;
        
        switch (this.align) 
        {
            case "top": top = this.elemTop;arrowTop = 10;break;
            case "bottom": top = this.elemTop + this.elemHeight - this.contentHeight;arrowTop = this.contentHeight - 16 - 10;break;
            default: top = this.elemTop + this.elemHalfHeight - this.contentHalfHeight;arrowTop = this.contentHalfHeight - 8;break;
        }
        
        this.$floater.show().css({top: top, left: left});
        if (this.hasArrow)
        {
            this.$arrow.addClass("z-right").css({left: arrowLeft, top: arrowTop});
        }
    },
    placeRight: function()
    {//放置右边
        var left = this.elemLeft + this.elemWidth + this.left;
        var top, arrowTop;
        
        switch (this.align) 
        {
            case "top": top = this.elemTop;arrowTop = 10;break;
            case "bottom": top = this.elemTop + this.elemHeight - this.contentHeight;arrowTop = this.contentHeight - 16 - 10;break;
            default: top = this.elemTop + this.elemHalfHeight - this.contentHalfHeight;arrowTop = this.contentHalfHeight - 8;break;
        }
        
        this.$floater.show().css({left: left, top: top});
        if (this.hasArrow)
        {
            this.$arrow.addClass("z-left").css("top", arrowTop);
            this.$content.css("left", "9px");
        }
    },
    placeBottom: function()
    {//放置下面
        var top = this.elemTop + this.$elem.offsetHeight() + this.top;
        var left, arrowLeft;
        
        switch (this.align) 
        {
            case "left": left = this.elemLeft;arrowLeft = 10;break;
            case "right": left = this.elemLeft - this.contentWidth + this.elemWidth;arrowLeft = this.contentWidth - 16 - 10;break;
            default: left = this.elemLeft + this.elemHalfWidth - this.contentHalfWidth;arrowLeft = this.contentHalfWidth - 8;break;
        }
        
        this.$floater.show().css({left: left, top: top});
        if (this.hasArrow)
        {
            this.$arrow.addClass("z-up").css("left", arrowLeft);
            this.$content.css("top", "7px");
        }
    },
    show: function()
    {//定义到元素的下方
    
        //1.设置箭头边框和背景
        if (this.hasArrow)
        {
            this.$arrow.css("border-color", this.arrowBorderColor());
            this.$arrow.find("span").css("border-color", this.arrowBackgroundColor());
        }
        
        //2.根据指定方位放置
        switch(this.placement)
        {
            case "top":return this.placeTop();
            case "left":return this.placeLeft();
            case "right":return this.placeRight();
            default:return this.placeBottom();
        }
    },
    hide:function(e)
    {//鼠标在元素和提示中间不关闭
        var x = Z.E.clientX(e);
        var y = Z.E.clientY(e);
        var tx = this.$elem.clientX();
        var ty = this.$elem.clientY();
        var tw = this.$elem.offsetWidth();
        var th = this.$elem.offsetHeight();
        
        switch(this.placement)
        {
            case "top":
            {
                if (x > tx && x < (tx+tw) && y < ty && y > (ty-this.top))
                    return;
                break;
            }
            case "left":
            {
                if (x > (tx-this.left) && x < (tx+tw) && y > ty && y < (ty+th))
                    return;
                break;
            }
            case "right":
            {
                if (x > (tx+tw) && x < (tx+tw+this.left) && y > ty && y < (ty+th))
                    return;
                break;
            }
            default:
            {//bottom
                if (x > tx && x < (tx+tw) && y > (ty+th) && y < (ty+th+this.top))
                    return;
            }
        }

        this.$floater.hide();
    },
    remove: function()
    {
        this.$floater.remove();
    }
};


/************************************************************************/
//以下为Z.Tooltip，提供两种方式创建：
// 1、使用Z.Tooltip/Z.Tooltip.close进行手动设置和关闭
// 2、通过配置属性data-role="tooltip"来配置数据，并有data-text属性和可选属性可选的属性data-options值为样式格式handle:click;placement:bottom;align:center;top:5px;left:5px;width:200px;height:25px;color:#000;
//     <span data-role="tooltip" data-text="测试弹出提示框是否正常显示">需要提示的内容</span>
//     <span data-role="tooltip" data-options="top:1px;width:200px;height:25px;" data-text="测试弹出提示框是否正常显示">需要提示的内容</span>
/************************************************************************/
Z.Tooltip = function(elem, param)
{
    Z.Tooltip.close(elem);
    var tooltip = new Z.Floater({elem: elem});
    for (var key in param){
        tooltip[key] = param[key];
    }
    tooltip.execute();
    Z.Tooltip.cache.push(tooltip);
    return tooltip;
};

//缓存和关闭函数
Z.Tooltip.cache = [];
Z.Tooltip.close = function(elem)
{
    if (!elem)
    {//删除所有
        Z.each(Z.Tooltip.cache, function(tooltip){
            tooltip.remove();
        });
        Z.Tooltip.cache = [];
    }
    else
    {//删除一个
        Z.each(Z.Tooltip.cache, function(tooltip, i)
        {
            if (tooltip.elem == elem)
            {
                Z.Tooltip.cache.splice(i, 1);
                tooltip.remove();
                return true;
            }
        });
    }
};

//初始化和窗口缩放时重新加载
Z.Tooltip.load = function()
{
    //先关闭原来的
    Z.Tooltip.close();
    
    //再重新新增
    Z("[data-role=z-tooltip]").each(function(elem)
    {
        if (!Z.EL.has(elem, "data-text"))
            return;
        
        //获取配置的内容参数
        var $elem = Z(elem);
        var id = $elem.attr("data-id");
        var text = $elem.attr("data-text");
        var expression = $elem.attr("data-options");
        var options = Z.AR.toObject(expression, ";");
        
        var event = options && options.event || "hover";
        var placement = options && options.placement || "bottom";
        var align = options && options.align || "center";
        var top = Z.S.prefixNum(options && options.top || 0);
        var left = Z.S.prefixNum(options && options.left || 0);
        var width = Z.S.prefixNum(options && options.width || 130);
        var height = Z.S.prefixNum(options && options.height || 25);
        
        var arrow = options && options.arrow || "true";
        var hasArrow = "true" == arrow;
        
        var color = options && options.color || "#333";
        var borderColor = options && options.borderColor || "#c6c6c6";
        var backgroundColor = options && options.backgroundColor || "#fff";
        
        var tooltip = new Z.Floater({elem: elem, event: event, placement: placement, align: align, 
            top: top, left: left, width: width, height: height, 
            hasArrow: hasArrow, id: id, text: text,
            color: color, borderColor: borderColor, backgroundColor: backgroundColor});
        tooltip.execute();
        
        Z.Tooltip.cache.push(tooltip);
    });
};

Z.onload(Z.Tooltip.load);
Z(window).resize(Z.Tooltip.load);

//END
})(zhiqim);